/* 
* nur den inhalt der main bearbeitet und eine funktion user_interface() hinzugefügt
* main jetzt viel kürzer
* fehler in network.c gefunden bei network_send && server_start fehlt die if NULL
*    abfrage nach dem öffenen der datei
* user_interface schon bisschen getestet. bis jetzt geht alles! :D
____________________________________________________

*/

//! die includes aus main.c wieder einfügen (also die hier ersetzen)
#include <stdio.h>
#include <stdlib.h>
int debug;
#define DAT "senden.dat"
#define VERSION 1.1
#include <string.h>

/*ne kleine spaß funktion für düstere momente, wenn einfach nichts mehr geht
 */
void easteregg(char *OS){
	printf("\n\
\n cowsay -f tux '0==strcmp(OS,\"Linux\")?printf(\"Coding Is Fun!\\n\"):printf(\":-(\");\n\n\
 _________________________________________\n\
/ 0==strcmp(OS,\"Linux\")?printf(\"Coding Is \\\n\
\\   Fun!\"):printf(\"düdümm :-(\");          /\n\
 ----------------------------------------- \n\
   \\\n\
    \\\n\
        .--.\n\
       |o_o |\n\
       |:_/ |\n\
      //   \\ \\\n\
     (|     | )\n\
    /'\\_   _/`\\\n\
    \\___)=(___/\n\
\n Der Programmierer hat %s an void easteregg(char *OS) übergeben:\n    > Daraus folgt -> ",OS);
	0==strcmp(OS,"Linux")?printf("Coding Is Fun!\n"):printf("Düdümm :-(\n");
}

/*schaltet den debug modus an oder aus
 */
int debug_mode(void){
	if(0 == debug){
		debug=-1;
		printf("Debug Modus Aktiviert\n");
	}else{
		debug = 0;
		printf("Debug Modus Deaktiviert\n");
	}
	return debug;
}

/*zeigt informationen über die entwickler und das programm
 */
void print_info(void){
	printf("\n ~Belegarbeit Rechnernetze Kommunikationssysteme Version %g~\n\
\n\
Info ausgeben über parameter\n\
 Teilnehmer 1:\n\
\t Name:  Tim Malich\n\
\t S-Num: s64629 Matrikl-Nr.: 29508\n\
\n\
 Teilnehmer 2:\n\
\t Name:  AAA BBBBBBB\n\
\t S-Num: s12345 Matrikl-Nr.: 12345\n\
\n\
 Teilnehmer 3:\n\
\t Name:  CCC DDD\n\
\t S-Num: s09876 Matrikl-Nr.: 22222\n\
\n\
 Teilnehmer 4:\n\
\t Name:  EEE FFF\n\
\t S-Num: s12345 Matrikl-Nr.: 12345\n\
", VERSION);
}

/*prüft den port auf gültigkeit
 */
unsigned int portcheck(unsigned int port){
	if( port > 0 && port < 69911 )
		return 0;
	return 1;
}

/*prüft ip adresse auf gültigkeit
 * RET:  0 -> ip gültig; -1 -> ip war ungültig
 * NOTE: Bei ungültigkeit wird die ip auf localhost ::1 gesetzt
 */
int ipcheck(char *ip){
	if( strcmp(ip, "::2") )
		return 1;
	return 0;
}

/* ein auswahl menu für die einstellungen
 * IN:
 * OUT:  das menu, informationen über version und entwicker, debug modus
 * RET:   0 -> Server soll gestartet werden
 *        1 -> Client soll gestartet werden
 *       10 -> beides soll gestartet werden
 * NOTE: bei aktivem debug modus wird mehr auf der konsole ausgegeben 
 *       und der server verliert zu testzwecken ein paar pakete (verlustsimulation)
 */ 
int menu(void){
	int zahl=-1;
	char c='\0';
	printf("\n\
____________________________________________________\n\
|                                                  |\n\
| ~Belegarbeit Rechnernetze Kommunikationssysteme~ |\n\
| _______________ _______________ _______________  |\n\
| |             | |             | |             |  |\n\
| | 0 -> Server | | 1 -> Client | |  2 -> Info  |  |\n\
| |_____________| |_____________| |_____________|  |\n\
| _______________________________ _______________  |\n\
| |                             | |             |  |\n\
| |    3 -> Debugmode ON/OFF    | | 4 -> Close! |  |\n\
| |_____________________________| |_____________|  |\n\
|                                                  |\n\
|      Tipp: 10 startet Server und Client!         |\n\
|__________________________________________________|\n\
\n\
> \
");

	while ( (zahl > 1) || (zahl < 0)  || (zahl!=10) ){
		scanf("%d", &zahl ); 
		//tastatur puffer leeren, falls zeichen eingegeben wurden
		while ( (c = fgetc(stdin)) != EOF && (c!='\n'));
		switch (zahl){
			case 1111:
				easteregg("Linux");
				break;
			case 10:
				// löscht die ausgaben vom bildschirm, vorteil: wird übersichtlicher (windows + *nix)
				if (system("cls")) system("clear");
				return zahl;
			case 4: exit(0);
				break;
			case 3: 
				debug_mode();
			//	fflush(stdin);
				break;
			case 2: 
				print_info();
			//	fflush(stdin);
				break;
			case 1: 
				//löscht die ausgaben vom bildschirm, vorteil: wird übersichtlicher (windows + *nix)
				if (system("cls")) system("clear");
			//	fflush(stdin);
				return zahl;
				break;
			case 0: 
				// löscht die ausgaben vom bildschirm, vorteil: wird übersichtlicher (windows + *nix)
				if (system("cls")) system("clear");
			//	fflush(stdin);
				return zahl;
				break;
		}
	printf("\n0 -> Server; 1 -> Client; 2 -> Info; 3 -> Debugmode; 4 -> Close\n");
	}
	return zahl;
}

/* Kümmert sich um die eingaben vom benutzer und überprüft einige eingaben
 * IN:   argc und argv aus der main
 * OUT:  siehe OUT von menu
 * RET:  0 -> server starten; 1 -> client starten; 10 -> server und client starten
 *	     die variablen (ip, port und filename) mit befüllen. (call by reference)
 * NOTE: - wurde nur erstellt damit die main funktion übersichtlich bleibt
 *       - noch unklar was passiert wenn die datei leerzeiche enthält (im linux gehts, noch im Windows testen)
 */ 
int user_interface(int argc, char*argv[], char *ip, unsigned int *port, char *filename){
	int i=0, startSoC=-1; //start Server or Client
	FILE *file=NULL;
	char c;
	
	//auswerten der parameter:
	for(i=1; i<argc; i++){
		//info ausgeben!
		if( 0==strcmp("-i", argv[i]) || 0==strcmp("-I", argv[i]) )			
			print_info();
		//debug mode an!
		else if( 0==strcmp("-d", argv[i]) || 0==strcmp("-D", argv[i]) )		
			debug=-1;
		//dateinamen übergeben?
		else if( 0==strcmp("-f", argv[i]) || 0==strcmp("-F", argv[i] ) ){
			if( i+1 < argc ){
				free(filename);
				filename=NULL;
				filename = filename?filename:malloc(strlen(argv[i+1])+1);
				if( NULL==filename ){
					if( debug ) printf(" D user_interface:\n   > Fataler Fehler, nicht genügend Hauptspeicher für den Dateinamen\n");
				}
				strcpy(filename,argv[i+1]);
			}
		}
		//ip adressen flag übergeben?
		else if( 0==strcmp("-ip", argv[i]) || 0==strcmp("-Ip", argv[i]) || 0==strcmp("IP",argv[i]) ){
			//ip übergeben?
			if( i+1 < argc ){
				strncpy(ip,argv[i+1], 32);
			}
		}
		//port übergeben?
		else if( 0==strcmp("-p", argv[i]) || 0==strcmp("-P", argv[i]) ){
			if( i+1 < argc){
				*port=atoi(argv[i+1]);
				portcheck(*port);
			}
				
		}
		//server starten?
		else if( 0==strcmp("-s", argv[i]) || 0==strcmp("-S", argv[i]) ){	//server starten
			if(startSoC==1) startSoC=10;
			else startSoC=0;
		}
		//client starten?
		else if( 0==strcmp("-c", argv[i]) || 0==strcmp("-C", argv[i]) ){	//client starten 
			if(startSoC==0) startSoC=10;
			else startSoC=1;
		}
	}
	//überprüfung ob jetzt auch alle parameter valide sind
	while( 0 != ipcheck(ip) ){
		printf(" > Ihre IPv6 Adresse \"%s\" ist leider nicht gültig! Bitte versuchen Sie es erneut!\n Ipv6: ", ip);
		scanf("%32s",ip);
		//zur sicherheit nochmal den puffer leeren
		while ( (c = fgetc(stdin)) != EOF && (c!='\n'));
	}
	while( 0 != portcheck(*port) ){
		printf(" > Der eingegebene Port ist leider nicht gültig! Bitte versuchen Sie es erneut!\n Port: ");
		scanf("%d", port ); 
		//tastatur puffer leeren, falls zeichen eingegeben wurden
		while ( (c = fgetc(stdin)) != EOF && (c!='\n'));
	}
	while( NULL == (file=fopen( filename, "rb" )) ){
		printf(" > Der eingegebene Dateiname \"%s\" ist leider nicht gültig! Bitte versuchen Sie es erneut! (Max. 1024 Zeichen!)\n Datei: ", filename);
		free(filename);
		filename=malloc(sizeof(char)*1025);
		if( NULL==filename ){
			debug?printf(" D user_interface:\n   > Fataler Fehler, nicht genügend Hauptspeicher für den Dateinamen\n"):0;
		}
		scanf("%1024s",filename);
		printf("%s\n",filename);
	}
	fclose(file);
	
	//falls weder -s noch -c übergeben wurde dann starte menü	
	if(startSoC!=0 && startSoC!=1 && startSoC!=10)						//man könnte auch nach ==-1 fragen, finde diese lösung aber eindeutiger
		startSoC=menu();
	else if( 0 == startSoC )
		return 0;
	else if( 10 == startSoC )
		return 10;
	else if( 1 == startSoC || 10 == startSoC )
		return 1;
	return startSoC;
}

int main(int argc, char *argv[]){
	char ip[32]="::1";
	char *filename=NULL;//[150]=DAT; //speicher allozieren
	unsigned int port=0;
	int startSoC=-1;
//	DWORD threadId = 0; 
//	HANDLE threadHandle = NULL;
//	char p[100000];
	/*parameter optionen 
	[1][1][1][1][1] = [Info ausgeben][Debug ON][Server starten][Client starten][filename vorhanden]
	*/
	//int parmopt[2]={0,0}; 
//	int zahl=-1;
		
	debug = -1; //standardmäßig auf aus stellen	
	
	startSoC=user_interface(argc, argv, ip, &port, filename);
	if( 10 == startSoC ){
		printf("Starte Server Thread und dananach client\n");
		//warte 2 sekunden
		printf("Starte Client\n");
	}else if( 0 == startSoC ){
		printf("Starte Server Thread\n");
	}else if( 1 == startSoC ){
		printf("Starte Client\n");
	}
	else
		if(debug) printf(" D user_interface()\n   > user_interface hat einen falschen Wert zurück gegeben: %d!\n", startSoC);
			
/*
    threadHandle = CreateThread(
		0, // keine Security 
		0, // default-Stack
		start_server,
		port, // 0=kein Parameter
		0, // normal erzeugen 
		&threadId // threadId
		); //Abgewandelte Version von: http://www.devmentor.ch/teaching/additional/01I/Semester5/Abend9/Threads.pdf

	if (threadHandle == NULL) {
		if(debug) printf("D   > Fehler, Server thread konnte nicht gestartet werden!\n");
		ExitProcess(3);
	}
	
	CloseHandle (threadHandle);

*/	

	/*anmerkung:
	* switch anweisung unpraktikabel, da die übergabe auch ausgewertet werden soll
	* wenn zu viele parameter übergeben wurden.
	*/
	/*
	if(argc > 4)
		printf("Parameter: %s %s %s %s\n", argv[1], argv[2], argv[3], argv[4]);
	else if(argc > 3)
		printf("Parameter: %s %s %s\n", argv[1], argv[2], argv[3]);
	else if(argc > 2)
		printf("Parameter: %s %s\n", argv[1], argv[2]);
	else if(argc > 1)
		printf("Parameter: %s\n", argv[1]);
	else
//		zahl=menu();

	if(1==zahl)
//		network_send(filename,ip,port);


	//ausgeben der parameterlister
	for(i=1; i<argc; i++)
		printf("%s ", argv[i]);
	printf("\n");
	
	for(i=1; i<argc; i++){
		if( 0==strcmp("-s", argv[i]) || 0==strcmp("-S", argv[i]) )
			printf("AJJJOOO\n");
	}
	*/
	getchar();
	return 0;
}
